package fr.inserm.u674.chcdbweb.model.DTO;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * This class represents a Data Transfer Object for a Tissue. This DTO can be used throughout all
 * layers, the data layer, the controller layer and the view layer
 * 
 * @author Thomas Burguiere based on the tutorial by BalusC
 * @link http://balusc.blogspot.com/2008/07/dao-tutorial-data-layer.html
 */
/**
 * @author Thomas Burguiere
 * 
 */
public class Tissue {

	private Integer chcID;
	private String tissueTypeID;

	private Tissue masterTissue;

	private Integer patient_patientID;
	private Integer histologicDiagnosis_HistologicDiagnosisID;
	private String tissueComment;

	private String quantityLeft;
	private List<Tissue> associatedTissues;
	private List<TissueExtraction> tissueExtractions;

	private LinkedHashMap<String, EAVModality> eavData;

	public Tissue() {
	}

	/**
	 * Minimal constructor
	 * 
	 * @param chcID
	 *            the numeric part of a standard CHC ID
	 * @param tissueTypeID
	 *            the Tissue Type
	 */
	public Tissue(Integer chcID, String tissueTypeID) throws IllegalArgumentException {
		if (chcID == null || chcID < 1 || tissueTypeID == null || tissueTypeID.trim().length() == 0)
			throw new IllegalArgumentException("The chcID (" + chcID + ") or the TissueTypeID ("
				+ tissueTypeID + ") is null or invalid");
		this.chcID = chcID;
		this.tissueTypeID = tissueTypeID;
	}

	public Tissue(String rawCHCID) {
		Matcher chcMatcher =
			Pattern.compile("(chc)?0*(\\d+)(.+)", Pattern.CASE_INSENSITIVE).matcher(rawCHCID);
		if (chcMatcher.matches()) {
			this.chcID = Integer.parseInt(chcMatcher.group(2));
			this.tissueTypeID = chcMatcher.group(3);
		}
		else
			throw new IllegalArgumentException("this rawCHCID : " + rawCHCID + " is invalid.");
	}

	/**
	 * @param chcID
	 *            Integer
	 * @param tissueTypeID
	 *            String
	 * @param masterTissue
	 *            Tissue
	 * @param patient_patientID
	 * @param histologicDiagnosis_HistologicDiagnosisID
	 * @param tissueComment
	 */
	public Tissue(Integer chcID, String tissueTypeID, Tissue masterTissue,
		Integer patient_patientID, Integer histologicDiagnosis_HistologicDiagnosisID,
		String tissueComment) {
		this(chcID, tissueTypeID);
		this.masterTissue = masterTissue;
		this.patient_patientID = patient_patientID;
		this.histologicDiagnosis_HistologicDiagnosisID = histologicDiagnosis_HistologicDiagnosisID;
		this.tissueComment = tissueComment;
	}

	public Tissue(Integer chcID, String tissueTypeID, Tissue masterTissue) {
		this(chcID, tissueTypeID);
		this.masterTissue = masterTissue;
	}

	public Integer getChcID() {
		return chcID;
	}

	public void setChcID(Integer chcID) {
		this.chcID = chcID;
	}

	public String getTissueTypeID() {
		return tissueTypeID;
	}

	public void setTissueTypeID(String tissueTypeID) {
		this.tissueTypeID = tissueTypeID;
	}

	public Tissue getMasterTissue() {
		return masterTissue;
	}

	public void setMasterTissue(Tissue masterTissue) {
		this.masterTissue = masterTissue;
	}

	public Integer getPatient_patientID() {
		return patient_patientID;
	}

	public void setPatient_patientID(Integer patient_patientID) {
		this.patient_patientID = patient_patientID;
	}

	public Integer getHistologicDiagnosis_HistologicDiagnosisID() {
		return histologicDiagnosis_HistologicDiagnosisID;
	}

	public void setHistologicDiagnosis_HistologicDiagnosisID(
		Integer histologicDiagnosis_HistologicDiagnosisID) {
		this.histologicDiagnosis_HistologicDiagnosisID = histologicDiagnosis_HistologicDiagnosisID;
	}

	public String getTissueComment() {
		return tissueComment;
	}

	public void setTissueComment(String tissueComment) {
		this.tissueComment = tissueComment;
	}

	public String getQuantityLeft() {
		return quantityLeft;
	}

	public void setQuantityLeft(String quantityLeft) {
		this.quantityLeft = quantityLeft;
	}

	public void setAssociatedTissues(List<Tissue> associatedTissues) {
		this.associatedTissues = associatedTissues;
	}

	public List<Tissue> getAssociatedTissues() {
		return associatedTissues;
	}

	public List<TissueExtraction> getTissueExtractions() {
		return tissueExtractions;
	}

	public void setTissueExtractions(List<TissueExtraction> tissueExtractions) {
		this.tissueExtractions = tissueExtractions;
	}

	public LinkedHashMap<String, EAVModality> getEavData() {
		return eavData;
	}

	public void setEavData(LinkedHashMap<String, EAVModality> eavData) {
		this.eavData = eavData;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof Tissue && ((Tissue) obj).getChcID().equals(chcID)
			&& ((Tissue) obj).getTissueTypeID().equals(tissueTypeID)) {
			return true;
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		if (chcID != null && tissueTypeID != null)
			return this.getClass().hashCode() + chcID.hashCode() + tissueTypeID.hashCode();
		else
			return super.hashCode();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		if (chcID < 10)
			return "CHC00" + chcID.toString() + tissueTypeID;
		else if (chcID < 100)
			return "CHC0" + chcID.toString() + tissueTypeID;
		else
			return "CHC" + chcID.toString() + tissueTypeID;
	}

	public static boolean isRawCHCIDValid(String rawCHCID) {
		Matcher chcMatcher =
			Pattern.compile("(chc)?0*(\\d+)(.+)", Pattern.CASE_INSENSITIVE).matcher(rawCHCID);
		return chcMatcher.matches();
	}

	public Boolean isMasterTissue() {
		return this.masterTissue == null;
	}

}